Add a points layer to the base plot.

Set the point transparency to 0.5. Set shape = “.”, the point size of 1 pixel.

Update the point shape to remove the line outlines by setting shape to 16.

library(ggplot2)
library(dplyr)
library(forcats)

# Plot price vs. carat, colored by clarity
plt_price_vs_carat_by_clarity <- ggplot(diamonds, aes(carat, price, color = clarity))

# Add a point layer with tiny points
plt_price_vs_carat_by_clarity + geom_point(alpha = 0.5, shape = ".")


# Set transparency to 0.5
plt_price_vs_carat_by_clarity + geom_point(alpha = 0.5, shape = 16)

Create a base plot plt_mpg_vs_fcyl_by_fam of fcyl by mpg, colored by fam. Add a points layer to the base plot.

Add some jittering by using position_jitter(), setting the width to 0.3.

Alternatively, use position_jitterdodge(). Set jitter.width and dodge.width to 0.3 to separate subgroups further.

# add 'fcyl' column as cyl column converted to a factor &
# a 'fam' column as am column converted to a factor
mtcars <- mutate(mtcars, fcyl = as_factor(cyl), fam = as_factor(am))

# Plot base
plt_mpg_vs_fcyl_by_fam <- ggplot(mtcars, 
    aes(x = fcyl, y = mpg, color = fam))

# Default points are shown for comparison
plt_mpg_vs_fcyl_by_fam + geom_point()


# Alter the point positions by jittering, width 0.3
plt_mpg_vs_fcyl_by_fam + geom_point(position = position_jitter(width = 0.3))


# Now jitter and dodge the point positions
plt_mpg_vs_fcyl_by_fam + geom_point(position = position_jitterdodge(jitter.width = 0.3, dodge.width = 0.3))

Change the points layer into a jitter layer. Reduce the jitter layer’s width by setting the width argument to 0.1.

Let’s use a different approach:

Within geom_point(), set position to “jitter”.

Provide an alternative specification:

Have the position argument call position_jitter() with a width of 0.1.

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  # Swap for jitter layer with width 0.1
  geom_jitter(alpha = 0.5,
  width = 0.1)



ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  # Set the position to jitter
  geom_point(position = "jitter", alpha = 0.5)


ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  # Use a jitter position function with width 0.1
  geom_point(position = position_jitter(width = 0.1), alpha = 0.5)

Examine the Vocab dataset using str(). Using Vocab, draw a plot of vocabulary vs education. Add a point layer. Replace the point layer with a jitter layer.

library(carData) #load package that contains Vocab

# Examine the structure of Vocab
str(Vocab)
'data.frame':   30351 obs. of  4 variables:
 $ year      : num  1974 1974 1974 1974 1974 ...
 $ sex       : Factor w/ 2 levels "Female","Male": 2 2 1 1 1 2 2 2 1 1 ...
 $ education : num  14 16 10 10 12 16 17 10 12 11 ...
 $ vocabulary: num  9 9 9 5 8 8 9 5 3 5 ...
 - attr(*, "na.action")= 'omit' Named int  1 2 3 4 5 6 7 8 9 10 ...
  ..- attr(*, "names")= chr  "19720001" "19720002" "19720003" "19720004" ...
# Plot vocabulary vs. education
ggplot(Vocab, aes(x = education, y = vocabulary)) +
# Add a point layer  
geom_point()


ggplot(Vocab, aes(education, vocabulary)) +
  # Change to a jitter layer
  geom_jitter()


ggplot(Vocab, aes(education, vocabulary)) +
  # Set the transparency to 0.2
  geom_jitter(alpha = 0.2)

  
ggplot(Vocab, aes(education, vocabulary)) +
  # Set the shape to 1
  geom_jitter(alpha = 0.2, shape = 1)

NA
NA

Using mtcars, map mpg onto the x aesthetic. Add a histogram layer using geom_histogram().

Set the histogram binwidth to 1.

# Plot mpg
ggplot(mtcars, aes(x = mpg)) +
  # Add a histogram layer
  geom_histogram()


ggplot(mtcars, aes(x = mpg)) +
  # Set the binwidth to 1
  geom_histogram(binwidth = 1)


# Map y to ..density..
ggplot(mtcars, aes(x= mpg, y = ..density..)) +
  geom_histogram(binwidth = 1)


datacamp_light_blue <- "#51A8C9"

ggplot(mtcars, aes(mpg, ..density..)) +
  # Set the fill color to datacamp_light_blue
  geom_histogram(binwidth = 1, fill = datacamp_light_blue)

Update the aesthetics so that the fill color of the bars is determined by fam.

Update the histogram layer to position the bars side-by-side, that is, “dodge”.

Update the histogram layer so the bars’ positions “fill” the y-axis.

Update the histogram layer so bars are top of each other, using the “identity” position. So each bar can be seen, set alpha to 0.4.

# Update the aesthetics so the fill color is by fam
ggplot(mtcars, aes(mpg, fill = fam)) +
  geom_histogram(binwidth = 1)


ggplot(mtcars, aes(mpg, fill = fam)) +
  # Change the position to dodge
  geom_histogram(binwidth = 1, position = "dodge")


ggplot(mtcars, aes(mpg, fill = fam)) +
  # Change the position to fill
  geom_histogram(binwidth = 1, position = "fill")


ggplot(mtcars, aes(mpg, fill = fam)) +
  # Change the position to identity, with transparency 0.4
  geom_histogram(alpha = 0.4, binwidth = 1, position = "identity")

Using mtcars, plot fcyl, filled by fam. Add a bar layer using geom_bar().

Set the bar position argument to “fill”.

Change the bar position argument to “dodge”.

# Plot fcyl, filled by fam
ggplot(mtcars, aes(x = fcyl, fill = fam)) +
  # Add a bar layer
  geom_bar()


ggplot(mtcars, aes(x = fcyl, fill = fam)) +
  # Set the position to "fill"
  geom_bar(position = "fill")


ggplot(mtcars, aes(fcyl, fill = fam)) +
  # Change the position to "dodge"
  geom_bar(position = "dodge")

Use the functional form of the bar position: replace “dodge” with a call to position_dodge(). Set its width to 0.2.

Set the bar transparency level of the bars to 0.6.

ggplot(mtcars, aes(cyl, fill = fam)) +
  # Change position to use the functional form, with width 0.2
  geom_bar(position = position_dodge(width = 0.2))


ggplot(mtcars, aes(cyl, fill = fam)) +
  # Set the transparency to 0.6
  geom_bar(alpha = 0.6, position = position_dodge(width = 0.2))

Plot the Vocab dataset, mapping education onto x and vocabulary onto fill.

Add a bar layer, setting position to “fill”.

Add a brewer fill scale, using the default palette (don’t pass any arguments). Notice how this generates a warning message and an incomplete plot.

# Plot education, filled by vocabulary
ggplot(Vocab, aes(x = education, fill = vocabulary))


# Plot education, filled by vocabulary
ggplot(Vocab, aes(x = education, fill = vocabulary)) +
  # Add a bar layer with position "fill"
  geom_bar(position = "fill")


# Plot education, filled by vocabulary
ggplot(Vocab, aes(x = education, fill = vocabulary)) +
  # Add a bar layer with position "fill"
  geom_bar(position = "fill") +
  # Add a brewer fill scale with default palette
    scale_fill_brewer()

Print the head of the economics dataset. Plot unemploy vs. date as a line plot.

Adjust the y-axis aesthetic of the plot so that it represents the proportion of the population that is unemployed.

# Print the head of economics
head(economics)

# Using economics, plot unemploy vs. date
ggplot(economics, aes(x = date, y = unemploy)) +
  # Make it a line plot
  geom_line()


# Change the y-axis to the proportion of the population that is unemployed
ggplot(economics, aes(x = date, y = unemploy/pop)) +
  geom_line()

Use str() in the console to examine the structure of both fish.species and fish.tidy. Plot only the Rainbow salmon time series with geom_line().

Plot only the Pink salmon time series with geom_line().

Now try and plot all time series in a single plot.

Plot the fish.tidy dataset, mapping Year to x and Capture to y. group by fish species within the aesthetics of geom_line().

Let’s add color to the previous plot to distinguish between the different time series.

Plot the fish.tidy dataset again, this time making sure to color by Species.

# Load fish.species file from csv, create tidyframe fish.tidy
fish.species <- read.csv("fish_species.csv")
fish.tidy <- gather(fish.species, Species, Capture, -Year)

# Plot the Rainbow Salmon time series
ggplot(fish.species, aes(x = Year, y = Rainbow)) +
  geom_line()


# Plot the Pink Salmon time series
ggplot(fish.species, aes(x = Year, y = Pink)) +
  geom_line()


# Plot multiple time-series by grouping by species
ggplot(fish.tidy, aes(x = Year, y = Capture)) +
  geom_line(aes(group = Species))


# Plot multiple time-series by coloring by species
ggplot(fish.tidy, aes(x = Year, y = Capture, color = Species)) +
  geom_line(aes(group = Species))

LS0tCnRpdGxlOiAiR2VvbWV0cmllcyIKc3VidGl0bGU6ICJJbnRyb2R1Y3Rpb24gdG8gRGF0YSBWaXN1YWxpemF0aW9uIHdpdGggZ2dwbG90MiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKQWRkIGEgcG9pbnRzIGxheWVyIHRvIHRoZSBiYXNlIHBsb3QuCgpTZXQgdGhlIHBvaW50IHRyYW5zcGFyZW5jeSB0byAwLjUuClNldCBzaGFwZSA9ICIuIiwgdGhlIHBvaW50IHNpemUgb2YgMSBwaXhlbC4KClVwZGF0ZSB0aGUgcG9pbnQgc2hhcGUgdG8gcmVtb3ZlIHRoZSBsaW5lIG91dGxpbmVzIGJ5IHNldHRpbmcgc2hhcGUgdG8gMTYuCgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShmb3JjYXRzKQoKIyBQbG90IHByaWNlIHZzLiBjYXJhdCwgY29sb3JlZCBieSBjbGFyaXR5CnBsdF9wcmljZV92c19jYXJhdF9ieV9jbGFyaXR5IDwtIGdncGxvdChkaWFtb25kcywgYWVzKGNhcmF0LCBwcmljZSwgY29sb3IgPSBjbGFyaXR5KSkKCiMgQWRkIGEgcG9pbnQgbGF5ZXIgd2l0aCB0aW55IHBvaW50cwpwbHRfcHJpY2VfdnNfY2FyYXRfYnlfY2xhcml0eSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNoYXBlID0gIi4iKQoKIyBTZXQgdHJhbnNwYXJlbmN5IHRvIDAuNQpwbHRfcHJpY2VfdnNfY2FyYXRfYnlfY2xhcml0eSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUsIHNoYXBlID0gMTYpCgpgYGAKCkNyZWF0ZSBhIGJhc2UgcGxvdCBwbHRfbXBnX3ZzX2ZjeWxfYnlfZmFtIG9mIGZjeWwgYnkgbXBnLCBjb2xvcmVkIGJ5IGZhbS4KQWRkIGEgcG9pbnRzIGxheWVyIHRvIHRoZSBiYXNlIHBsb3QuCgpBZGQgc29tZSBqaXR0ZXJpbmcgYnkgdXNpbmcgcG9zaXRpb25faml0dGVyKCksIHNldHRpbmcgdGhlIHdpZHRoIHRvIDAuMy4KCkFsdGVybmF0aXZlbHksIHVzZSBwb3NpdGlvbl9qaXR0ZXJkb2RnZSgpLiBTZXQgaml0dGVyLndpZHRoIGFuZCBkb2RnZS53aWR0aCB0byAwLjMgdG8gc2VwYXJhdGUgc3ViZ3JvdXBzIGZ1cnRoZXIuCgoKYGBge3J9CiMgYWRkICdmY3lsJyBjb2x1bW4gYXMgY3lsIGNvbHVtbiBjb252ZXJ0ZWQgdG8gYSBmYWN0b3IgJgojIGEgJ2ZhbScgY29sdW1uIGFzIGFtIGNvbHVtbiBjb252ZXJ0ZWQgdG8gYSBmYWN0b3IKbXRjYXJzIDwtIG11dGF0ZShtdGNhcnMsIGZjeWwgPSBhc19mYWN0b3IoY3lsKSwgZmFtID0gYXNfZmFjdG9yKGFtKSkKCiMgUGxvdCBiYXNlCnBsdF9tcGdfdnNfZmN5bF9ieV9mYW0gPC0gZ2dwbG90KG10Y2FycywgCiAgICBhZXMoeCA9IGZjeWwsIHkgPSBtcGcsIGNvbG9yID0gZmFtKSkKCiMgRGVmYXVsdCBwb2ludHMgYXJlIHNob3duIGZvciBjb21wYXJpc29uCnBsdF9tcGdfdnNfZmN5bF9ieV9mYW0gKyBnZW9tX3BvaW50KCkKCiMgQWx0ZXIgdGhlIHBvaW50IHBvc2l0aW9ucyBieSBqaXR0ZXJpbmcsIHdpZHRoIDAuMwpwbHRfbXBnX3ZzX2ZjeWxfYnlfZmFtICsgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMykpCgojIE5vdyBqaXR0ZXIgYW5kIGRvZGdlIHRoZSBwb2ludCBwb3NpdGlvbnMKcGx0X21wZ192c19mY3lsX2J5X2ZhbSArIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjMsIGRvZGdlLndpZHRoID0gMC4zKSkKCmBgYAoKQ2hhbmdlIHRoZSBwb2ludHMgbGF5ZXIgaW50byBhIGppdHRlciBsYXllci4KUmVkdWNlIHRoZSBqaXR0ZXIgbGF5ZXIncyB3aWR0aCBieSBzZXR0aW5nIHRoZSB3aWR0aCBhcmd1bWVudCB0byAwLjEuCgpMZXQncyB1c2UgYSBkaWZmZXJlbnQgYXBwcm9hY2g6CgpXaXRoaW4gZ2VvbV9wb2ludCgpLCBzZXQgcG9zaXRpb24gdG8gImppdHRlciIuCgpQcm92aWRlIGFuIGFsdGVybmF0aXZlIHNwZWNpZmljYXRpb246CgpIYXZlIHRoZSBwb3NpdGlvbiBhcmd1bWVudCBjYWxsIHBvc2l0aW9uX2ppdHRlcigpIHdpdGggYSB3aWR0aCBvZiAwLjEuCgoKYGBge3J9CmdncGxvdChpcmlzLCBhZXMoeCA9IFNlcGFsLkxlbmd0aCwgeSA9IFNlcGFsLldpZHRoLCBjb2xvciA9IFNwZWNpZXMpKSArCiAgIyBTd2FwIGZvciBqaXR0ZXIgbGF5ZXIgd2l0aCB3aWR0aCAwLjEKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuNSwKICB3aWR0aCA9IDAuMSkKCgpnZ3Bsb3QoaXJpcywgYWVzKHggPSBTZXBhbC5MZW5ndGgsIHkgPSBTZXBhbC5XaWR0aCwgY29sb3IgPSBTcGVjaWVzKSkgKwogICMgU2V0IHRoZSBwb3NpdGlvbiB0byBqaXR0ZXIKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gImppdHRlciIsIGFscGhhID0gMC41KQoKZ2dwbG90KGlyaXMsIGFlcyh4ID0gU2VwYWwuTGVuZ3RoLCB5ID0gU2VwYWwuV2lkdGgsIGNvbG9yID0gU3BlY2llcykpICsKICAjIFVzZSBhIGppdHRlciBwb3NpdGlvbiBmdW5jdGlvbiB3aXRoIHdpZHRoIDAuMQogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjEpLCBhbHBoYSA9IDAuNSkKCmBgYAoKCkV4YW1pbmUgdGhlIFZvY2FiIGRhdGFzZXQgdXNpbmcgc3RyKCkuClVzaW5nIFZvY2FiLCBkcmF3IGEgcGxvdCBvZiB2b2NhYnVsYXJ5IHZzIGVkdWNhdGlvbi4KQWRkIGEgcG9pbnQgbGF5ZXIuClJlcGxhY2UgdGhlIHBvaW50IGxheWVyIHdpdGggYSBqaXR0ZXIgbGF5ZXIuCgoKYGBge3J9CmxpYnJhcnkoY2FyRGF0YSkgI2xvYWQgcGFja2FnZSB0aGF0IGNvbnRhaW5zIFZvY2FiCgojIEV4YW1pbmUgdGhlIHN0cnVjdHVyZSBvZiBWb2NhYgpzdHIoVm9jYWIpCgojIFBsb3Qgdm9jYWJ1bGFyeSB2cy4gZWR1Y2F0aW9uCmdncGxvdChWb2NhYiwgYWVzKHggPSBlZHVjYXRpb24sIHkgPSB2b2NhYnVsYXJ5KSkgKwojIEFkZCBhIHBvaW50IGxheWVyICAKZ2VvbV9wb2ludCgpCgpnZ3Bsb3QoVm9jYWIsIGFlcyhlZHVjYXRpb24sIHZvY2FidWxhcnkpKSArCiAgIyBDaGFuZ2UgdG8gYSBqaXR0ZXIgbGF5ZXIKICBnZW9tX2ppdHRlcigpCgpnZ3Bsb3QoVm9jYWIsIGFlcyhlZHVjYXRpb24sIHZvY2FidWxhcnkpKSArCiAgIyBTZXQgdGhlIHRyYW5zcGFyZW5jeSB0byAwLjIKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMikKICAKZ2dwbG90KFZvY2FiLCBhZXMoZWR1Y2F0aW9uLCB2b2NhYnVsYXJ5KSkgKwogICMgU2V0IHRoZSBzaGFwZSB0byAxCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNoYXBlID0gMSkKCgpgYGAKClVzaW5nIG10Y2FycywgbWFwIG1wZyBvbnRvIHRoZSB4IGFlc3RoZXRpYy4KQWRkIGEgaGlzdG9ncmFtIGxheWVyIHVzaW5nIGdlb21faGlzdG9ncmFtKCkuCgpTZXQgdGhlIGhpc3RvZ3JhbSBiaW53aWR0aCB0byAxLgoKCmBgYHtyfQojIFBsb3QgbXBnCmdncGxvdChtdGNhcnMsIGFlcyh4ID0gbXBnKSkgKwogICMgQWRkIGEgaGlzdG9ncmFtIGxheWVyCiAgZ2VvbV9oaXN0b2dyYW0oKQoKZ2dwbG90KG10Y2FycywgYWVzKHggPSBtcGcpKSArCiAgIyBTZXQgdGhlIGJpbndpZHRoIHRvIDEKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpCgojIE1hcCB5IHRvIC4uZGVuc2l0eS4uCmdncGxvdChtdGNhcnMsIGFlcyh4PSBtcGcsIHkgPSAuLmRlbnNpdHkuLikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpCgpkYXRhY2FtcF9saWdodF9ibHVlIDwtICIjNTFBOEM5IgoKZ2dwbG90KG10Y2FycywgYWVzKG1wZywgLi5kZW5zaXR5Li4pKSArCiAgIyBTZXQgdGhlIGZpbGwgY29sb3IgdG8gZGF0YWNhbXBfbGlnaHRfYmx1ZQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9IGRhdGFjYW1wX2xpZ2h0X2JsdWUpCgpgYGAKClVwZGF0ZSB0aGUgYWVzdGhldGljcyBzbyB0aGF0IHRoZSBmaWxsIGNvbG9yIG9mIHRoZSBiYXJzIGlzIGRldGVybWluZWQgYnkgZmFtLgoKVXBkYXRlIHRoZSBoaXN0b2dyYW0gbGF5ZXIgdG8gcG9zaXRpb24gdGhlIGJhcnMgc2lkZS1ieS1zaWRlLCB0aGF0IGlzLCAiZG9kZ2UiLgoKVXBkYXRlIHRoZSBoaXN0b2dyYW0gbGF5ZXIgc28gdGhlIGJhcnMnIHBvc2l0aW9ucyAiZmlsbCIgdGhlIHktYXhpcy4KClVwZGF0ZSB0aGUgaGlzdG9ncmFtIGxheWVyIHNvIGJhcnMgYXJlIHRvcCBvZiBlYWNoIG90aGVyLCB1c2luZyB0aGUgImlkZW50aXR5IiBwb3NpdGlvbi4gU28gZWFjaCBiYXIgY2FuIGJlIHNlZW4sIHNldCBhbHBoYSB0byAwLjQuCgoKYGBge3J9CiMgVXBkYXRlIHRoZSBhZXN0aGV0aWNzIHNvIHRoZSBmaWxsIGNvbG9yIGlzIGJ5IGZhbQpnZ3Bsb3QobXRjYXJzLCBhZXMobXBnLCBmaWxsID0gZmFtKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkKCmdncGxvdChtdGNhcnMsIGFlcyhtcGcsIGZpbGwgPSBmYW0pKSArCiAgIyBDaGFuZ2UgdGhlIHBvc2l0aW9uIHRvIGRvZGdlCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBwb3NpdGlvbiA9ICJkb2RnZSIpCgpnZ3Bsb3QobXRjYXJzLCBhZXMobXBnLCBmaWxsID0gZmFtKSkgKwogICMgQ2hhbmdlIHRoZSBwb3NpdGlvbiB0byBmaWxsCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBwb3NpdGlvbiA9ICJmaWxsIikKCmdncGxvdChtdGNhcnMsIGFlcyhtcGcsIGZpbGwgPSBmYW0pKSArCiAgIyBDaGFuZ2UgdGhlIHBvc2l0aW9uIHRvIGlkZW50aXR5LCB3aXRoIHRyYW5zcGFyZW5jeSAwLjQKICBnZW9tX2hpc3RvZ3JhbShhbHBoYSA9IDAuNCwgYmlud2lkdGggPSAxLCBwb3NpdGlvbiA9ICJpZGVudGl0eSIpCmBgYAoKClVzaW5nIG10Y2FycywgcGxvdCBmY3lsLCBmaWxsZWQgYnkgZmFtLgpBZGQgYSBiYXIgbGF5ZXIgdXNpbmcgZ2VvbV9iYXIoKS4KClNldCB0aGUgYmFyIHBvc2l0aW9uIGFyZ3VtZW50IHRvICJmaWxsIi4KCkNoYW5nZSB0aGUgYmFyIHBvc2l0aW9uIGFyZ3VtZW50IHRvICJkb2RnZSIuCgoKYGBge3J9CiMgUGxvdCBmY3lsLCBmaWxsZWQgYnkgZmFtCmdncGxvdChtdGNhcnMsIGFlcyh4ID0gZmN5bCwgZmlsbCA9IGZhbSkpICsKICAjIEFkZCBhIGJhciBsYXllcgogIGdlb21fYmFyKCkKCmdncGxvdChtdGNhcnMsIGFlcyh4ID0gZmN5bCwgZmlsbCA9IGZhbSkpICsKICAjIFNldCB0aGUgcG9zaXRpb24gdG8gImZpbGwiCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpCgpnZ3Bsb3QobXRjYXJzLCBhZXMoZmN5bCwgZmlsbCA9IGZhbSkpICsKICAjIENoYW5nZSB0aGUgcG9zaXRpb24gdG8gImRvZGdlIgogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikKCmBgYAoKVXNlIHRoZSBmdW5jdGlvbmFsIGZvcm0gb2YgdGhlIGJhciBwb3NpdGlvbjogcmVwbGFjZSAiZG9kZ2UiIHdpdGggYSBjYWxsIHRvIHBvc2l0aW9uX2RvZGdlKCkuClNldCBpdHMgd2lkdGggdG8gMC4yLgoKU2V0IHRoZSBiYXIgdHJhbnNwYXJlbmN5IGxldmVsIG9mIHRoZSBiYXJzIHRvIDAuNi4KCgpgYGB7cn0KZ2dwbG90KG10Y2FycywgYWVzKGN5bCwgZmlsbCA9IGZhbSkpICsKICAjIENoYW5nZSBwb3NpdGlvbiB0byB1c2UgdGhlIGZ1bmN0aW9uYWwgZm9ybSwgd2l0aCB3aWR0aCAwLjIKICBnZW9tX2Jhcihwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSkKCmdncGxvdChtdGNhcnMsIGFlcyhjeWwsIGZpbGwgPSBmYW0pKSArCiAgIyBTZXQgdGhlIHRyYW5zcGFyZW5jeSB0byAwLjYKICBnZW9tX2JhcihhbHBoYSA9IDAuNiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMikpCgpgYGAKCgpQbG90IHRoZSBWb2NhYiBkYXRhc2V0LCBtYXBwaW5nIGVkdWNhdGlvbiBvbnRvIHggYW5kIHZvY2FidWxhcnkgb250byBmaWxsLgoKQWRkIGEgYmFyIGxheWVyLCBzZXR0aW5nIHBvc2l0aW9uIHRvICJmaWxsIi4KCkFkZCBhIGJyZXdlciBmaWxsIHNjYWxlLCB1c2luZyB0aGUgZGVmYXVsdCBwYWxldHRlIChkb24ndCBwYXNzIGFueSBhcmd1bWVudHMpLiBOb3RpY2UgaG93IHRoaXMgZ2VuZXJhdGVzIGEgd2FybmluZyBtZXNzYWdlIGFuZCBhbiBpbmNvbXBsZXRlIHBsb3QuCgoKYGBge3J9CiMgUGxvdCBlZHVjYXRpb24sIGZpbGxlZCBieSB2b2NhYnVsYXJ5CmdncGxvdChWb2NhYiwgYWVzKHggPSBlZHVjYXRpb24sIGZpbGwgPSB2b2NhYnVsYXJ5KSkKCiMgUGxvdCBlZHVjYXRpb24sIGZpbGxlZCBieSB2b2NhYnVsYXJ5CmdncGxvdChWb2NhYiwgYWVzKHggPSBlZHVjYXRpb24sIGZpbGwgPSB2b2NhYnVsYXJ5KSkgKwogICMgQWRkIGEgYmFyIGxheWVyIHdpdGggcG9zaXRpb24gImZpbGwiCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpCgojIFBsb3QgZWR1Y2F0aW9uLCBmaWxsZWQgYnkgdm9jYWJ1bGFyeQpnZ3Bsb3QoVm9jYWIsIGFlcyh4ID0gZWR1Y2F0aW9uLCBmaWxsID0gdm9jYWJ1bGFyeSkpICsKICAjIEFkZCBhIGJhciBsYXllciB3aXRoIHBvc2l0aW9uICJmaWxsIgogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArCiAgIyBBZGQgYSBicmV3ZXIgZmlsbCBzY2FsZSB3aXRoIGRlZmF1bHQgcGFsZXR0ZQogICAgc2NhbGVfZmlsbF9icmV3ZXIoKQoKYGBgCgpQcmludCB0aGUgaGVhZCBvZiB0aGUgZWNvbm9taWNzIGRhdGFzZXQuClBsb3QgdW5lbXBsb3kgdnMuIGRhdGUgYXMgYSBsaW5lIHBsb3QuCgpBZGp1c3QgdGhlIHktYXhpcyBhZXN0aGV0aWMgb2YgdGhlIHBsb3Qgc28gdGhhdCBpdCByZXByZXNlbnRzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBwb3B1bGF0aW9uIHRoYXQgaXMgdW5lbXBsb3llZC4KCgoKYGBge3J9CiMgUHJpbnQgdGhlIGhlYWQgb2YgZWNvbm9taWNzCmhlYWQoZWNvbm9taWNzKQoKIyBVc2luZyBlY29ub21pY3MsIHBsb3QgdW5lbXBsb3kgdnMuIGRhdGUKZ2dwbG90KGVjb25vbWljcywgYWVzKHggPSBkYXRlLCB5ID0gdW5lbXBsb3kpKSArCiAgIyBNYWtlIGl0IGEgbGluZSBwbG90CiAgZ2VvbV9saW5lKCkKCiMgQ2hhbmdlIHRoZSB5LWF4aXMgdG8gdGhlIHByb3BvcnRpb24gb2YgdGhlIHBvcHVsYXRpb24gdGhhdCBpcyB1bmVtcGxveWVkCmdncGxvdChlY29ub21pY3MsIGFlcyh4ID0gZGF0ZSwgeSA9IHVuZW1wbG95L3BvcCkpICsKICBnZW9tX2xpbmUoKQoKYGBgCgpVc2Ugc3RyKCkgaW4gdGhlIGNvbnNvbGUgdG8gZXhhbWluZSB0aGUgc3RydWN0dXJlIG9mIGJvdGggZmlzaC5zcGVjaWVzIGFuZCBmaXNoLnRpZHkuClBsb3Qgb25seSB0aGUgUmFpbmJvdyBzYWxtb24gdGltZSBzZXJpZXMgd2l0aCBnZW9tX2xpbmUoKS4KClBsb3Qgb25seSB0aGUgUGluayBzYWxtb24gdGltZSBzZXJpZXMgd2l0aCBnZW9tX2xpbmUoKS4KCk5vdyB0cnkgYW5kIHBsb3QgYWxsIHRpbWUgc2VyaWVzIGluIGEgc2luZ2xlIHBsb3QuCgpQbG90IHRoZSBmaXNoLnRpZHkgZGF0YXNldCwgbWFwcGluZyBZZWFyIHRvIHggYW5kIENhcHR1cmUgdG8geS4KZ3JvdXAgYnkgZmlzaCBzcGVjaWVzIHdpdGhpbiB0aGUgYWVzdGhldGljcyBvZiBnZW9tX2xpbmUoKS4KCkxldCdzIGFkZCBjb2xvciB0byB0aGUgcHJldmlvdXMgcGxvdCB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIHRoZSBkaWZmZXJlbnQgdGltZSBzZXJpZXMuCgpQbG90IHRoZSBmaXNoLnRpZHkgZGF0YXNldCBhZ2FpbiwgdGhpcyB0aW1lIG1ha2luZyBzdXJlIHRvIGNvbG9yIGJ5IFNwZWNpZXMuCgoKYGBge3J9CiMgTG9hZCBmaXNoLnNwZWNpZXMgZmlsZSBmcm9tIGNzdiwgY3JlYXRlIHRpZHlmcmFtZSBmaXNoLnRpZHkKZmlzaC5zcGVjaWVzIDwtIHJlYWQuY3N2KCJmaXNoX3NwZWNpZXMuY3N2IikKZmlzaC50aWR5IDwtIGdhdGhlcihmaXNoLnNwZWNpZXMsIFNwZWNpZXMsIENhcHR1cmUsIC1ZZWFyKQoKIyBQbG90IHRoZSBSYWluYm93IFNhbG1vbiB0aW1lIHNlcmllcwpnZ3Bsb3QoZmlzaC5zcGVjaWVzLCBhZXMoeCA9IFllYXIsIHkgPSBSYWluYm93KSkgKwogIGdlb21fbGluZSgpCgojIFBsb3QgdGhlIFBpbmsgU2FsbW9uIHRpbWUgc2VyaWVzCmdncGxvdChmaXNoLnNwZWNpZXMsIGFlcyh4ID0gWWVhciwgeSA9IFBpbmspKSArCiAgZ2VvbV9saW5lKCkKCiMgUGxvdCBtdWx0aXBsZSB0aW1lLXNlcmllcyBieSBncm91cGluZyBieSBzcGVjaWVzCmdncGxvdChmaXNoLnRpZHksIGFlcyh4ID0gWWVhciwgeSA9IENhcHR1cmUpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFNwZWNpZXMpKQoKIyBQbG90IG11bHRpcGxlIHRpbWUtc2VyaWVzIGJ5IGNvbG9yaW5nIGJ5IHNwZWNpZXMKZ2dwbG90KGZpc2gudGlkeSwgYWVzKHggPSBZZWFyLCB5ID0gQ2FwdHVyZSwgY29sb3IgPSBTcGVjaWVzKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTcGVjaWVzKSkKCmBgYAoK